#coding=utf-8

from . import api

from flask import request,abort,current_app,jsonify,make_response,json
# 导入图片验证码所需要的东西
from iHome.utils.captcha.captcha import captcha

from iHome import redis_store

from iHome import constants

from iHome.utils.response_code import RET

import re

import random

from iHome import constants

from iHome.utils.sms import CCP

from iHome.models import User


# 发送短信验证码后端实现
@api.route('/sms',methods=["POST"])
def send_sms():
    """
    1. 获取参数并判断是否为空
    2. 判断手机号是否合法
    3. 取到redis中缓存的图片验证码内容
    4. 对比图片验证码内容，如果对比成功
    5. 发送短信验证码
    6. 给前端响应结果
    :return:
    """
    # 1,获取参数并判断是否为空
    # 首先获取到的数据是json字符串形式
    data = request.data
    # 将它装变成json字典类型
    data_dict=json.loads(data)
    mobile=data_dict.get("mobile")
    image_code=data_dict.get("image_code")
    image_code_id=data_dict.get("image_code_id")

    if not all([mobile,image_code,image_code_id]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数不全")

    # 2 判断手机号是否合法
    if not re.match("^1[34578][0-9]{9}$",mobile):
        return jsonify(errno=RET.PARAMERR,errmsg="手机号格式不正确")

    # 3 取到redis中缓存的图片验证码内容
    try:
        real_image_code=redis_store.get("ImageCode_"+image_code_id)
        redis_store.delete("ImageCode_"+image_code_id)
    except Exception as e :
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="获取验证码内容失败")
    # 如果取出来的验证码是None，那么代表验证码过期
    if not real_image_code:
        return jsonify(errno=RET.DATAERR,errmsg="验证码过期")

    # 4. 对比图片验证码内容，如果对比成功,比较验证码内容的小写形式
    if real_image_code.lower() != image_code.lower():
        return jsonify(errno=RET.DATAERR,errmsg="验证码不正确")
    # 4.1 断当前手机号是否注册过，如果注册过，直接返回错误
    try:
        user=User.query.filter_by(mobile=mobile).first()
    except Exception as e :
        # 一但进入到exception里面的话，如果没有定义user的话，代表会往下执行
        # 往下执行的过程中会去判断user是否存在，如果user没定义，将抛出未定义异常，给user定义：user=None才能进项下面的if user:判断
        user=None
        current_app.logger.error(e)
    if user:
        return jsonify(errno=RET.DATAEXIST,errmsg="当前手机号已经注册")


    # 5 发送短信验证码
    #5.1 生成短信验证码
    result=random.randint(0,999999)
    sms_code="%06d"%result
    print sms_code
    current_app.logger.debug("短信验证码内容是：%s" %sms_code)
    # 5.2 发送,应该是CPP的实例对象CPP（）来调用 ,将下面这行代码注释掉来进行调试。
    # result=CCP().send_template_sms(mobile,[sms_code,constants.SMS_CODE_REDIS_EXPIRES/60],"1")
    # if result==0:
    #     return jsonify(errno=RET.THIRDERR,errmsg="发送短信验证码失败")

    # 6存储验证码内容以便后续校验
    try:
        redis_store.set("SMS_"+mobile,sms_code,constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="保存验证码失败")
    # 7 发送成功
    return jsonify(errno=RET.OK,errmsg="发送成功")


# 生成图片验证码接口
# /api/v1.0/imagecode   可以/api/v1.0作为api蓝图的前缀注册到app当中，api匹配的路由只写/imagecode就可以了
@api.route("/imagecode")
def get_image_code():
    """
    1：取到图片编码
    2：生成图片验证码
    3：存储到redis当中（key是图片编码，值是验证码的文字内容）
    4：返回图片给浏览器
    :return:
    """

    #1：取到图片编码
    # args是请求参数，即问号？后面跟的内容，它在请求路径后面跟着
    args=request.args
    # 获取请求参数中cur对应的值
    cur=args.get("cur")
    # 删除pre先获取pre
    pre=args.get("pre")
    #判断获取到的url对应的值
    if not cur:
        # 如果url没有值，即是用户没有传图片id ,抛出403错误
        abort(403)

    # 2：生成图片验证码
    # 生成图片验证码
    _,text,image = captcha.generate_captcha()

    # 为了测试输出到控制台
    current_app.logger.debug(text)

    # 3：存储到redis当中（key是图片编码，值是验证码的文字内容）
    try:
        # 删除之前的验证码
        if pre:
            redis_store.delete("ImageCode_"+pre)
        # 通过数据库链接对象将验证码的内容写入到数据库当中（键，内容，过期时间）
        redis_store.set("ImageCode_"+cur,text,constants.IMAGE_CODE_REDIS_EXPIRES)
    except Exception as e:
        # 将该异常写入到日志当中
        current_app.logger.error(e)
        # 无法写入时，报数据库错误errno=RET.DBERR
        return jsonify(errno=RET.DBERR,errmsg="保存图片验证码失败")
    # 4：返回验证码图片   make_respoinse()这个函数可以生成一个响应对象
    response=make_response(image)
    # TODO:设置content-Type
    response.headers["Content-Type"] = "image/jpg"
    return response




